<template>
  <div class="page-content">
    <!--    表格上面一行-->
    <div class="content-header">
      <div class="left">
        <template v-if="isShowNewBtn">
          <el-button size="small" type="primary" @click="addBtn"
            >新建
          </el-button>
        </template>
        <el-dropdown v-if="isShowBatchBtn">
          <div class="btnOper">
            <span class="text">批量操作</span>
            <el-icon>
              <arrow-down />
            </el-icon>
          </div>
          <template #dropdown>
            <el-dropdown-menu>
              <template v-for="item in batchBtns" :key="item.label">
                <el-dropdown-item @click="batchBtnClick(item.type)">
                  {{ item.label }}
                </el-dropdown-item>
              </template>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        <template v-if="isToGetMoreIds">
          <el-link class="cancelBtn" type="primary" @click="cancelGetMoreIds"
            >取消全选
          </el-link>
        </template>
      </div>
      <div class="right">
        <el-tooltip effect="dark" content="刷新数据" placement="bottom">
          <el-icon class="icon" :size="14" @click="handleRefreshClick">
            <Refresh />
          </el-icon>
        </el-tooltip>
      </div>
    </div>
    <!--    table表格-->
    <el-table
      ref="tableRef"
      :row-key="treeRowKey"
      :tree-props="treeProps"
      :data="pageCommonStore.pageList"
      :stripe="layout.stripe"
      :border="layout.border"
      :size="layout.size"
      :height="layout.height"
      @selection-change="handleSelectionChange"
      style="width: 100%"
    >
      <template v-for="item in items" :key="item">
        <!--        展开行-->
        <template v-if="item.type === 'expand'">
          <el-table-column
            type="expand"
            :fixed="item.fixed"
            :label="item.label"
            :align="item.align ?? 'left'"
            :width="item.width"
            :min-width="item.minWidth"
            :show-overflow-tooltip="item.showOverflowTooltip"
          >
            <template #default="{ row }">
              <slot
                :name="item.slotName"
                v-bind="row"
                :prop="item.slotName"
              ></slot>
            </template>
          </el-table-column>
        </template>
        <!--        自定义内容-->
        <template v-else-if="item.type === 'custom'">
          <el-table-column
            :fixed="item.fixed"
            :label="item.label"
            :align="item.align ?? 'left'"
            :width="item.width"
            :min-width="item.minWidth"
            :show-overflow-tooltip="item.showOverflowTooltip"
          >
            <template #default="{ row }">
              <slot
                :name="item.slotName"
                v-bind="row"
                :prop="item.slotName"
              ></slot>
            </template>
          </el-table-column>
        </template>
        <!--        操作类型-->
        <template v-else-if="item.type === 'operation'">
          <el-table-column
            :fixed="item.fixed"
            :label="item.label"
            :align="item.align ?? 'left'"
            :width="item.width"
            :min-width="item.minWidth"
            :show-overflow-tooltip="item.showOverflowTooltip"
          >
            <template #default="{ row }">
              <el-dropdown>
                <div class="btnOper">
                  <span class="text">操作</span>
                  <el-icon :size="12">
                    <arrow-down />
                  </el-icon>
                </div>
                <template #dropdown>
                  <el-dropdown-menu>
                    <template v-for="btn in item.btns" :key="btn.label">
                      <el-dropdown-item @click="singleBtnClick(btn.type, row)">
                        {{ btn.label }}
                      </el-dropdown-item>
                    </template>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </template>
          </el-table-column>
        </template>
        <!--        普通展示-->
        <el-table-column
          v-else
          :type="item.type"
          :prop="item.prop"
          :fixed="item.fixed"
          :label="item.label"
          :align="item.align ?? 'left'"
          :width="item.width"
          :min-width="item.minWidth"
          :show-overflow-tooltip="item.showOverflowTooltip"
        />
      </template>
    </el-table>
    <!--    分页器-->
    <div class="pagination" v-if="isShowPagination">
      <el-pagination
        v-model:currentPage="pagination.current"
        v-model:page-size="pagination.size"
        :page-sizes="[10, 20, 30]"
        :small="true"
        layout="sizes,jumper, prev, pager, next, total"
        :total="pagination.total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    <!--      page-modal-->
    <page-modal
      ref="pageModalRef"
      :is-edit-btn="curBtnType === SingleBtns.Edit"
      v-bind="currentModalConfig"
      @cancelClick="cancelClick"
      @confirmClick="confirmClick"
    >
      <!--      插槽回传-->
      <template
        v-for="item in currentModalConfig?.form?.items"
        :key="item.slotName"
        v-slot:[item.slotName]="formItem"
      >
        <slot
          v-if="item.slotName"
          v-bind="formItem"
          :name="item.slotName"
        ></slot>
      </template>
    </page-modal>
  </div>
</template>

<script setup lang="ts">
import { computed, onUnmounted, ref, watchEffect } from 'vue'
import PageModal from '@/components/page-modal/page-modal.vue'
import bannedTimeConfig from '@/components/page-content/modal-config/banned-time'
import secondAuthConfig from '@/components/page-content/modal-config/second-auth'
import { useAccountStore, usePageCommonStore, useUserStore } from '@/store'
import { storeToRefs } from 'pinia'
import { BatchBtns, SingleBtns } from '@/global/constant'
import { ElMessageBox, ElNotification } from 'element-plus'

import type {
  IBatchBtn,
  IModalConfig,
  ITableItem,
  ITableLayout,
  SingleBtnType
} from '@/global/types'
import type { ElTable } from 'element-plus'
import merchantRejectConfig from '@/components/page-content/modal-config/merchant-reject'
import { reqSetRoleById } from '@/service/module/main/system/admin'

interface IProps {
  pageName: string
  layout: ITableLayout
  batchBtns?: IBatchBtn[]
  singleBtnConfig?: IModalConfig
  items: ITableItem[]
}

const emits = defineEmits(['singleBtnClick', 'cancelClick', 'confirmClick'])

const props = withDefaults(defineProps<IProps>(), {})

// 树形table的数据配置项
const treeChildren = () => {
  if (props.pageName === 'menu' || props.pageName === 'goodClassify')
    return 'children'
}
// eslint-disable-next-line vue/return-in-computed-property
const treeRowKey = computed(() => {
  if (props.pageName === 'menu') return 'menuId'
  if (props.pageName === 'goodClassify') return 'classifyId'
})
const treeProps = {
  children: treeChildren()
}
// 初始化
const tableRef = ref<InstanceType<typeof ElTable>>()
const pageModalRef = ref<InstanceType<typeof PageModal>>()
const curBtnType = ref('') // 当前操作的类型
const curRow = ref({}) // 当前选中行数据
let idPropName // row数据的id名字
const isToGetMoreIds = ref(false) // 是否需要请求500条批量id的标识
watchEffect(() => {
  // 动态指定id的属性名
  switch (props.pageName) {
    case 'user':
      idPropName = 'userId'
      break
    case 'merchant':
      idPropName = 'userId'
      break
    case 'merchantApply':
      idPropName = 'userId'
      break
    case 'role':
      idPropName = 'roleId'
      break
    case 'merchantType':
      idPropName = 'manageId'
      break
    case 'merchantUpgrade':
      idPropName = 'companyUpgradeId'
      break
    case 'admin':
      idPropName = 'userId'
      break
    case 'menu':
      idPropName = 'menuId'
      break
    case 'goodBrand':
      idPropName = 'brandId'
      break
    case 'goodClassify':
      idPropName = 'classifyId'
      break
  }
})

// 是否显示某些按钮
const isShowNewBtn = computed(() => {
  const isHiddenArr = [
    'user',
    'merchant',
    'merchantApply',
    'merchantUpgrade',
    'loginLog',
    'banned',
    'operationLog'
  ]
  return !isHiddenArr.includes(props.pageName)
})
// 是否显示某批量按钮
const isShowBatchBtn = computed(() => {
  const isHiddenArr = [
    'loginLog',
    'banned',
    'operationLog',
    'menu',
    'goodBrand',
    'goodSku',
    'goodClassify'
  ]
  return !isHiddenArr.includes(props.pageName)
})
// 是否显示分页器
const isShowPagination = computed(() => {
  const isHiddenArr = ['menu', 'goodClassify']
  return !isHiddenArr.includes(props.pageName)
})

// 仓库数据
const pageCommonStore = usePageCommonStore()
const { pagination, ids, merchantUpgradeInfos } = storeToRefs(pageCommonStore)
const accountStore = useAccountStore()
const userStore = useUserStore()

// 保存参数
let formData

// 首次加载数据
getPageData()

// 页面销毁页号更改为第1页
onUnmounted(() => {
  pageCommonStore.pagination.current = 1
})

// =============== ============================= 头部一些按钮 =====================================
// 组件库自带事件--获取当前选中的id
const checkedIds = ref<number[]>([])
const merchantIds = ref<number[]>([])
const merchantUpgradeData = ref<any[]>([])

const handleSelectionChange = (list: any[]) => {
  if (props.pageName === 'merchantApply') {
    merchantIds.value = list.map((item) => item['merchantId'])
  }
  if (props.pageName === 'merchantUpgrade') {
    merchantUpgradeData.value = list.map((item) => ({
      merchantId: item['merchantId'],
      applyStoreCompanyType: item['applyStoreCompanyType']
    }))
  }
  checkedIds.value = list.map((item) => item[idPropName])
  if (checkedIds.value.length >= pagination.value.size) {
    // 判断是否要请求最大选中id（500条）
    showMessageBox()
  } else {
    isToGetMoreIds.value = false
  }
}

watchEffect(() => {
  if (ids.value.length) {
    checkedIds.value = ids.value
    merchantIds.value = ids.value
  }
  if (merchantUpgradeInfos.value.length) {
    merchantUpgradeData.value = merchantUpgradeInfos.value
  }
})

// 批量操作
// 动态计算对话框配置
// eslint-disable-next-line vue/return-in-computed-property
const currentModalConfig = computed(() => {
  // 如果外面有传进来配置，那么下面直接不用执行，已经有表单配置了
  if (props.singleBtnConfig) return props.singleBtnConfig

  // 不同按钮的modal配置文件
  if (
    curBtnType.value === BatchBtns.Banned ||
    curBtnType.value === SingleBtns.Banned
  ) {
    return bannedTimeConfig // 封禁时间的框
  } else if (
    curBtnType.value === BatchBtns.Delete ||
    curBtnType.value === SingleBtns.Delete ||
    curBtnType.value === SingleBtns.ResetPwd
  ) {
    return secondAuthConfig // 二次认证的框
  } else if (curBtnType.value === SingleBtns.Reject) {
    return merchantRejectConfig // 驳回原因
  }
})

// 对话框确认按钮(子传父)
const confirmClick = async (info: any) => {
  pageModalRef.value?.setModalStatus(false)

  // 发请求获取500条id数据
  if (isToGetMoreIds.value) {
    await getMoreIds()
  }

  // 告诉父亲点击完成，应该把单操作的配置配置为空
  const updateInfo = (otherInfo: any) => {
    info = { ...info, ...otherInfo }
  }
  emits('confirmClick', curBtnType.value, updateInfo)

  // 根据不同类型进行不同的操作
  if (
    BatchBtns.Banned === curBtnType.value ||
    SingleBtns.Banned === curBtnType.value
  ) {
    // 1.发送封禁请求
    fetchBanned(info)
  } else if (
    BatchBtns.Delete === curBtnType.value ||
    SingleBtns.Delete === curBtnType.value
  ) {
    // 2.发送删除请求
    fetchDelete(info)
  } else if (SingleBtns.ResetPwd === curBtnType.value) {
    // 3.重置账户密码
    resetUserPwd(info)
  } else if (SingleBtns.Edit === curBtnType.value) {
    // 4.更新信息
    await fetchUpdate(info)
  } else if (
    SingleBtns.Add === curBtnType.value ||
    SingleBtns.RowAdd === curBtnType.value
  ) {
    // 5.新增数据
    fetchNew(info)
  } else if (SingleBtns.Reject === curBtnType.value) {
    // 6.驳回申请
    info = {
      ...info,
      merchantId: curRow.value['merchantId']
    }
    await pageCommonStore.reqRejectMerchantAction(props.pageName, info)
  } else if (SingleBtns.SetRole === curBtnType.value) {
    // 7.分配角色
    info = {
      ...info,
      userId: curRow.value['userId']
    }
    setRole(info)
  }
  pageCommonStore.curRow = {}
  console.log(info)

  // // 最后告诉父亲点击完成，应该把单操作的配置配置为空
  // emits('confirmClick', curBtnType.value)
}

// 取消按钮
const cancelClick = () => {
  pageModalRef.value?.setModalStatus(false)
  emits('cancelClick')
  pageCommonStore.curRow = {}
}
// 批量操作的按钮
const batchBtnClick = async (type: string) => {
  // 只要进行批量操作都要判断是否有选中的项
  if (!checkedIds.value.length) {
    ElNotification.info('请先选择数据~')
    return
  }

  // 更新批量操作的类型的状态
  curBtnType.value = type

  // 1.发送批量解封请求
  if (BatchBtns.UniteDisable === curBtnType.value) {
    if (isToGetMoreIds.value) {
      await getMoreIds()
      batchUniteDisable()
    } else {
      batchUniteDisable()
    }
    return
  }

  // 2. 批量通过
  if (BatchBtns.Pass === curBtnType.value) {
    if (isToGetMoreIds.value) {
      await getMoreIds()
      batchPassMerchant()
    } else {
      batchPassMerchant()
    }
    return
  }
  // 打开page-modal
  pageModalRef.value?.setModalStatus(true)
}

// 新增按钮
const addBtn = () => {
  curBtnType.value = SingleBtns.Add
  // 清除当前行信息，就不会保留编辑表单残留的信息
  pageCommonStore.curRow = {}
  // 将点击事件传出去
  emits('singleBtnClick', curBtnType.value, curRow.value)
}

// 单操作的按钮
const singleBtnClick = (type: SingleBtnType, row: any) => {
  // 1.更新单操作点击后的状态
  updateSingleBtnClickState(type, row)

  // 2.点击按钮发生的事件
  // 2.1、强制下线
  if (curBtnType.value === SingleBtns.KickOut) {
    kickOutUser()
    return
  }
  // 2.2、重置密码 和 驳回原因 查看详情  删除数据 都需要打开对话框
  if (
    curBtnType.value === SingleBtns.ResetPwd ||
    curBtnType.value === SingleBtns.Reject ||
    curBtnType.value === SingleBtns.Delete
  ) {
    // 打开page-modal
    pageModalRef.value?.setModalStatus(true)
    return
  }
  // 2.3、通过商户申请
  if (curBtnType.value === SingleBtns.Pass) {
    passMerchant()
    return
  }

  // 将点击事件传出去
  emits('singleBtnClick', type, row)
}

// 取消全选的按钮
const cancelGetMoreIds = () => {
  pageCommonStore.ids = []
  tableRef.value?.clearSelection()
}

// 重置数据的按钮
const handleRefreshClick = () => {
  pagination.value.current = 1
  const info = {}
  if (props.pageName === 'goodSku') {
    info['productId'] = -1
  }
  getPageData(info)
}

// =========================================== 底部分页器 ===========================================
const handleSizeChange = (size: number) => {
  pagination.value.size = size
  getPageData(formData)
}
const handleCurrentChange = (current: number) => {
  pagination.value.current = current
  getPageData(formData)
}

// ========================================= 封装方法 ========================================
// 设置一个方法请空选中的行
function cleanAllChecked() {
  ids.value = []
  tableRef.value?.clearSelection()
}

// 封装一个方法给外面设置pageModal的显示与隐藏
function setModalStatus(isShowModal: boolean) {
  pageModalRef.value?.setModalStatus(isShowModal)
}

// 1.封装一个方法请求页面数据
function getPageData(info: any = {}) {
  // 1.请空所有选中的状态
  cleanAllChecked()
  // 2.发送请求获取数据
  formData = info
  const { current, size } = pagination.value
  pageCommonStore.fetchPageDataAction(props.pageName, {
    ...formData,
    current,
    size
  })
}

// 2.获取500条数据的id
async function getMoreIds() {
  const pageName = props.pageName
  // if (pageName === 'user') {
  const isMerchant =
    (pageName == 'merchantApply' || pageName == 'merchantUpgrade') &&
    curBtnType.value === BatchBtns.Pass
  let status = -1
  curBtnType.value === BatchBtns.Delete && (status = 2)
  curBtnType.value === BatchBtns.Banned && (status = 1)
  curBtnType.value === BatchBtns.UniteDisable && (status = 0)
  await pageCommonStore.getBatchIdsAction(pageName, status, isMerchant)
  // }
}

// 3.批量解封
function batchUniteDisable() {
  ElMessageBox.confirm('您是否要解封选中账号?', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'info',
    closeOnClickModal: false,
    buttonSize: 'small'
  }).then(() => {
    pageCommonStore.reqBatchUntieDisableAction(checkedIds.value, props.pageName)
  })
}

// 4.删除
function fetchDelete(info: any) {
  const password = info.password
  const pageName = props.pageName
  const btnType = curBtnType.value
  // skuType针对sku页面   1为规格值删除 0为规格删除
  let skuType = -1
  if (props.pageName === 'goodSku') {
    skuType = curRow.value['specificationValueId'] ? 1 : 0
    idPropName = curRow.value['specificationValueId']
      ? 'specificationValueId'
      : 'specificationId'
  }
  accountStore
    .reqSecCertificationAction(password, pageName, btnType, skuType)
    .then(() => {
      // 批量删除真正请求
      if (BatchBtns.Delete === curBtnType.value) {
        pageCommonStore.reqBatchDeleteDataAction(
          checkedIds.value,
          props.pageName
        )
      }
      // 单数据删除真正请求
      if (SingleBtns.Delete === curBtnType.value) {
        pageCommonStore.reqDeleteDataAction(
          curRow.value[idPropName],
          props.pageName,
          skuType
        )
      }
    })
}

// 5.是否展示500条数据的提示框
function showMessageBox() {
  ElMessageBox.confirm(
    '是否选择系统支持的最大批量操作条数(500条)?',
    '系统提示',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'info'
    }
  )
    .then(() => {
      isToGetMoreIds.value = true
    })
    .catch(() => {
      isToGetMoreIds.value = false
    })
}

// 6.封装一个方法让外面能改变curBtnType变量
function setCurBtnType(type: string) {
  curBtnType.value = type
}

// 7.封禁账号（批量/单个）
function fetchBanned(info: any) {
  if (curBtnType.value === BatchBtns.Banned) {
    pageCommonStore.reqBatchBannedByIdsAction(
      checkedIds.value,
      info['bannedTime'],
      props.pageName
    )
  }
  if (curBtnType.value === SingleBtns.Banned) {
    userStore.reqBannedUserAction(
      props.pageName,
      curRow.value[idPropName],
      info['bannedTime']
    )
  }
}

// 8.封装一个方法让外面设置当前的row
function setCurRow(row: any) {
  curRow.value = row
}

// 9.强制用户下线
function kickOutUser() {
  ElMessageBox.confirm('是否强制该用户下线?', '系统提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'info'
  }).then(() => {
    userStore.reqKickOutUserAction(curRow.value[idPropName])
  })
}

// 10.重置用户密码
function resetUserPwd(info: any) {
  accountStore
    .reqSecCertificationAction(info.password, props.pageName, curBtnType.value)
    .then(() => {
      userStore.reqResetUserPwdAction(curRow.value[idPropName])
    })
}

// 11.单个通过商户申请
function passMerchant() {
  ElMessageBox.confirm('是否通过该商户的申请?', '系统提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'info'
  }).then(() => {
    pageCommonStore.reqPassMerchantAction(
      props.pageName,
      curRow.value['merchantId'],
      curRow.value['applyStoreCompanyType']
    )
  })
}

// 12.批量通过商户申请
function batchPassMerchant() {
  ElMessageBox.confirm('是否通过选中商户的申请?', '系统提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'info'
  }).then(() => {
    let info = merchantIds.value
    if (props.pageName === 'merchantUpgrade') info = merchantUpgradeData.value
    pageCommonStore.reqBatchPassMerchantAction(props.pageName, info)
  })
}

// 13.分配角色
async function setRole(info: any) {
  await reqSetRoleById(info)
  await pageCommonStore.fetchPageDataAction(props.pageName, {
    current: 1,
    size: 10
  })
}

// 14.更新单按钮点击后的状态
function updateSingleBtnClickState(type: SingleBtnType, row: any) {
  curBtnType.value = type
  curRow.value = row
  pageCommonStore.curRow = row
  // 如果是编辑按钮, 还需要把当前行信息保存到store里供表单使用 (新增设置角色情况)
  // if (
  //   type === SingleBtns.Edit ||
  //   type === SingleBtns.SetRole ||
  //   type === SingleBtns.RowAdd
  // ) {
  //   pageCommonStore.curRow = row
  // } else pageCommonStore.curRow = {}
}

// 15.编辑操作
async function fetchUpdate(info: any) {
  // 15.1 sku页面的编辑有规格和规格值两种情况，需要特殊处理
  if (props.pageName === 'goodSku') {
    const operationType = curRow.value['specificationValueId'] ? 1 : 0
    idPropName = curRow.value['specificationValueId']
      ? 'specificationValueId'
      : 'specificationId'
    info.productId = curRow.value['productId']
    info.operationType = operationType
  }

  await pageCommonStore.updatePageInfoAction(props.pageName, {
    ...info,
    [idPropName]: curRow.value[idPropName]
  })
}

// 16.新增数据
async function fetchNew(info: any) {
  if (props.pageName === 'goodSku') {
    if (pageCommonStore.curRow.specificationId) {
      const specificationId = pageCommonStore.curRow.specificationId
      info = { ...info, specificationId }
    } else {
      info = { ...info, productId: -1 }
    }
  }
  await pageCommonStore.reqAddPageDataAction(props.pageName, info)
}

// ============================ 向外暴露 =================================
defineExpose({
  getPageData,
  setModalStatus,
  setCurBtnType,
  setCurRow,
  updateSingleBtnClickState
})
</script>

<style scoped lang="less">
.page-content {
  padding: 10px 15px;

  .content-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;

    .left {
      display: flex;
      justify-content: flex-start;
      align-items: center;

      .cancelBtn {
        font-size: 12px;
        margin-top: 3px;
      }
    }

    .right {
      .icon {
        cursor: pointer;
      }
    }
  }

  .btnOper {
    display: flex;
    //height: 100%;
    //align-items: center;
    margin: 5px 10px 0 20px;

    .text {
      margin-right: 5px;
      font-size: 13px;
    }
  }

  .pagination {
    display: flex;
    justify-content: flex-end;

    .el-pagination {
      margin: 20px 20px 10px 0;
    }
  }
}
</style>
